﻿using LitJson;
using RestAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TopVisionLog;
using TopVisionVideoStream.TopVisionCenter;

namespace TopVisionVideoStream.Mananger
{
    public class ConfCallManager
    {
        public delegate void ConfCallHandler(ConfCallResponse reult);

        public delegate void ConfCallMemberStateHandler(string result);

        public delegate void MeetingMemberStateHandler(string result);

        public event ConfCallHandler ConfCallStartup;

        public event ConfCallMemberStateHandler ConCallMemberState;

        public event ConfCallHandler ConfCallHaltReponse;

        public event MeetingMemberStateHandler MeetingMemberState;

        public event MeetingMemberStateHandler MeetingScreenModeState;

        public ConfCallResponse ConfInfo;

        public ConfCall_Recoding CallMode = ConfCall_Recoding.Yes;

        public ConfCall_ScreenMode ScreenMode = ConfCall_ScreenMode.Live;

        public int PicNum = 9;

        public string Title;

        public string RtmpPush;


        public void ConfCall(string[] members, ConfCall_Recoding callMode, ConfCall_ScreenMode screenMode, int picNum, string title, string rtmpPush)
        {
            CallMode = callMode;
            ScreenMode = screenMode;
            PicNum = picNum;
            Title = title;
            RtmpPush = rtmpPush;
            ConfCall(members);
        }

        public async void ConfCall(string[] members)
        {
            try
            {
                ConfInfo = null;

                List<string> _tmp = members.ToList();
                string calling = "";
                if (!_tmp.Contains(Configuration.Account)) _tmp.Insert(0, Configuration.Account);
                for (int i = 0; i < _tmp.Count; i++)
                {
                    calling += _tmp[i] + (i < _tmp.Count - 1 ? "^" : "");
                }

                WebVideoConfCall wvcc = new WebVideoConfCall(Configuration.CompanyID, calling, Configuration.Account,
                    ((int)CallMode).ToString(), ((int)ScreenMode).ToString(), ((int)PicNum).ToString(), Title, RtmpPush);

                wvcc.Call(ConfCallResult);

                int media = 0;

                int timer = 0;

                bool isTimeout = false;

                VideoCallManager vcm = new VideoCallManager();
                vcm.VideoCallEvent += (code, msg) =>
                {
                    if (code == 3)
                    {
                        media = code;
                        vcm.Dispose();
                    }
                };

                while (ConfInfo == null | media != 3)
                {
                    await Task.Delay(200);
                    timer += 200;
                    if (timer > 10 * 1000)
                    {
                        isTimeout = true;
                        break;
                    }
                }

                if (isTimeout) { return; }

                //string mms = "";

                //for (int i = 0; i < members.Length; i++)
                //{
                //    //WebVideoConfCtrlAdd wvcca = new WebVideoConfCtrlAdd(Configuration.CompanyID, members[i], ConfInfo.confid);
                //    //wvcca.Call((a) =>
                //    //{
                //    //    ConCallMemberState?.Invoke(a);
                //    //});

                //    if (members[i] == Configuration.Account) continue;

                //    mms += (i == 0 ? "" : "^") + members[i];

                //    await Task.Delay(500);
                //}

                //MemberInvite(mms);
            }
            catch (Exception ex)
            {
                string log = "ERR ConfCall : " + ex.Message;
                Console.WriteLine(log);
                TVLog.WriteLine(log);
            }
        }

        private void ConfCallResult(string response)
        {
            try
            {
                ConfCallResponse _ccr = JsonMapper.ToObject<ConfCallResponse>(response);

                ConfInfo = _ccr;

                ConfCallStartup?.Invoke(ConfInfo);

            }
            catch (Exception ex)
            {
                ConfInfo = null;

                Console.WriteLine("error : " + ex.Message);

                ConfCallStartup?.Invoke(null);

            }
        }

        public bool MemberInvite(string account)
        {
            try
            {
                Console.WriteLine("Invite :" + account);

                WebVideoConfCtrlAdd wvcca = new WebVideoConfCtrlAdd(Configuration.CompanyID, account, ConfInfo.confid);
                wvcca.Call((a) =>
                {
                    ConCallMemberState?.Invoke(a);
                });

                return true;
            }
            catch (Exception ex)
            {
                string log = "";
                if (ConfInfo == null) log = "ConfInfo is null";
                else log = ex.Message;
                TVLog.WriteLine(log);
                return false;
            }
        }

        public bool MemberKick(string account)
        {
            try
            {
                if (ConfInfo == null)
                {
                    throw new Exception("ConfInfo is null");
                }

                WebVideoConfCtrlDel wvccd = new WebVideoConfCtrlDel(Configuration.CompanyID, account, ConfInfo.confid);
                wvccd.Call((a) =>
                {
                    ConCallMemberState?.Invoke(a);
                });
                return true;
            }
            catch (Exception ex)
            {
                string log = "";
                if (ConfInfo == null) log = "ConfInfo is null";
                else log = ex.Message;
                TVLog.WriteLine(log);
                return false;
            }
        }

        public bool MemberCtrlView(string account)
        {
            try
            {
                if (ConfInfo == null)
                {
                    throw new Exception("ConfInfo is null");
                }

                WebVideoConfCtrlView wvccv = new WebVideoConfCtrlView(Configuration.CompanyID, account, ConfInfo.confid);
                wvccv.Call((a) =>
                {
                    ConCallMemberState?.Invoke(a);
                });
                return true;
            }
            catch (Exception ex)
            {
                string log = "";
                if (ConfInfo == null) log = "ConfInfo is null";
                else log = ex.Message;
                TVLog.WriteLine(log);
                return false;
            }
        }

        public bool MemberCtrlSilence(string account, string operation)
        {
            try
            {
                if (ConfInfo == null)
                {
                    throw new Exception("ConfInfo is null");
                }

                WebVideoConfsilence wvcs = new WebVideoConfsilence(Configuration.CompanyID, ConfInfo.confid, account, operation);
                wvcs.Call((a) =>
                {
                    ConCallMemberState?.Invoke(a);
                });
                return true;
            }
            catch (Exception ex)
            {
                string log = "";
                if (ConfInfo == null) log = "ConfInfo is null";
                else log = ex.Message;
                TVLog.WriteLine(log);
                return false;
            }
        }

        public bool ConfCallHalt()
        {
            try
            {
                if (ConfInfo == null)
                {
                    throw new Exception("ConfInfo is null");
                }

                WebVideoConfCtrlHalt wvcch = new WebVideoConfCtrlHalt(Configuration.CompanyID, ConfInfo.confid);
                wvcch.Call((a) =>
                {
                    try
                    {
                        ConfCallResponse _ccr = JsonMapper.ToObject<ConfCallResponse>(a);

                        ConfCallHaltReponse?.Invoke(_ccr);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("error : " + ex.Message);

                        ConfCallHaltReponse?.Invoke(null);
                    }
                    finally
                    {
                        ConfInfo = null;
                    }
                });
                return true;
            }
            catch (Exception ex)
            {
                string log = "";
                if (ConfInfo == null) log = "ConfInfo is null";
                else log = ex.Message;
                TVLog.WriteLine(log);
                return false;
            }
        }

        public void GetMeetingMemberState(Meeting_MemberStatus mstatus)
        {
            int _status = (int)mstatus;
            WebVideoConfMemberInfo wvcmi = new WebVideoConfMemberInfo(Configuration.CompanyID, ConfInfo.confid, _status.ToString());
            wvcmi.Call((r) =>
            {
                MeetingMemberState?.Invoke(r);
            });
        }

        public void SetMeetingScreen(ConfCall_ScreenMode mode)
        {
            WebVideoConfScreen wvcs = new WebVideoConfScreen(Configuration.CompanyID, ConfInfo.confid, ((int)mode).ToString());
            wvcs.Call((r) =>
            {
                MeetingScreenModeState?.Invoke(r);
            });
        }

        //public enum MeetingScreenGrid
        //{
        //    Single = 1,
        //    MultiSizeSame = 2,
        //    MultiSize = 3,
        //}

        public enum ConfCall_Recoding
        {
            No,
            Yes,
        }

        public enum ConfCall_ScreenMode
        {
            /// <summary>
            /// 直播
            /// </summary>
            Live,
            /// <summary>
            /// 两方
            /// </summary>
            P2P,
            /// <summary>
            /// 分屏
            /// </summary>
            Grid,
            /// <summary>
            /// 一大多小
            /// </summary>
            BTS,
            /// <summary>
            /// 二分屏
            /// </summary>
            Two,
            /// <summary>
            /// 四分屏
            /// </summary>
            Four,
        }

        public enum ConfCall_PicNum
        {
            One = 1,
            Two = 2,
            Four = 4,
            Six = 6,
            Nine = 9,
        }

        public enum Meeting_MemberStatus
        {
            /// <summary>
            /// 邀请中
            /// </summary>
            Inviting = 0,
            /// <summary>
            /// 会议中
            /// </summary>
            Meeting,
            /// <summary>
            /// 已退出
            /// </summary>
            Quited,
            /// <summary>
            /// 正在退出
            /// </summary>
            Quiting,
        }


        #region 个人中心

        /// <summary>
        /// 个人中心 发起会议
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfCall(TVCConferenceCallModel model, List<string> members)
        {
            TVCenter center = new TVCenter();

            model.companyid = Configuration.CompanyID;

            var result = await center.ConferenceCall(model);

            if (result.success && result.data != null)
            {
                ConfCallResponse _ccr = new ConfCallResponse();

                _ccr.number = result.data.number;
                _ccr.confid = result.data.confid;
                _ccr.callflowid = result.data.callflowid;
                _ccr.recordurl = result.data.recordurl;
                _ccr.status = "200";

                ConfInfo = _ccr;

                ConfCallStartup?.Invoke(ConfInfo);

                int media = 0;

                int timer = 0;

                bool isTimeout = false;

                VideoCallManager vcm = new VideoCallManager();

                vcm.VideoCallEvent += (code, msg) =>
                {
                    if (code == 3)
                    {
                        media = code;
                        vcm.Dispose();
                    }
                };

                while (ConfInfo == null | media != 3)
                {
                    await Task.Delay(200);
                    timer += 200;
                    if (timer > 30 * 1000)
                    {
                        isTimeout = true;
                        break;
                    }
                }

                if (isTimeout) { return; }

                await Task.Delay(1000);
                if (members.Count > 0)
                {
                    TVCConferencesConfctrladdModel addModel = new TVCConferencesConfctrladdModel();
                    addModel.companyid = Configuration.CompanyID;
                    addModel.confid = ConfInfo.confid;
                    addModel.called = string.IsNullOrEmpty(model.called) ? model.calling : model.called;
                    addModel.calling = string.Join("^", members);
                    var ret = await center.ConferenceConfctrladd(addModel);
                    if (ret.success)
                        ConCallMemberState?.Invoke(ret.msg);
                }
            }
            else
            {
                ConfCallStartup?.Invoke(new ConfCallResponse() { status = "400" });
            }
        }

        /// <summary>
        /// 视频会议控制-增加参与方
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfctrladd(TVCConferencesConfctrladdModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfctrladd(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议控制-减少参与方
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfctrldel(TVCConferencesConfctrldelModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfctrldel(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议控制-结束会议
        /// </summary>
        public async void TVCConfctrlhalt()
        {
            TVCConferencesConfctrlhaltModel model = new TVCConferencesConfctrlhaltModel();

            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfctrlhalt(model);

            if (result.success)
            {
                ConfCallHaltReponse?.Invoke(null);
            }

            ConfInfo = null;
        }

        /// <summary>
        /// 视频会议控制-设置画面布局
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfSreen(TVCConferenceConfscreenModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfscreen(model);

            if (result.success)
            {
                MeetingScreenModeState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议控制-设置大画面
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfctrlview(TVCConferenceConfctrlviewModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfctrlview(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议广播消息
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfmsg(TVCConferenceConfmsgModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfmsg(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议控制-控制播放视频文件
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfplayfile(TVCConferenceConfplayfileModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfplayfile(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 视频会议控制-控制静音哑音
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfsilence(TVCConferenceConfsilenceModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceConfsilence(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 查询会议状态
        /// </summary>
        /// <param name=""></param>
        public async void TVCConfGetconfinfo(TVCConferenceGetconfinfoModel model)
        {
            model.companyid = Configuration.CompanyID;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceGetconfinfo(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 查询单个会议信息
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfGetconfinfobyid(TVCConferenceGetconfinfobyidModel model)
        {
            model.companyid = Configuration.CompanyID;

            model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceGetconfinfobyid(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        /// <summary>
        /// 查询会议成员状态
        /// </summary>
        /// <param name="model"></param>
        public async void TVCConfGetconfmemberinfo(TVCConferencesConfGetconfmemberinfoModel model)
        {
            model.companyid = Configuration.CompanyID;

            //model.confid = ConfInfo.confid;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceGetconfmemberinfo(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }


        public async void TVCConfQueryrooms(TVCConferenceQueryroomsModel model)
        {
            model.companyid = Configuration.CompanyID;

            TVCenter center = new TVCenter();

            var result = await center.ConferenceQueryrooms(model);

            if (result.success)
            {
                ConCallMemberState?.Invoke(result.msg);
            }
        }

        #endregion
    }
}
